﻿using System;
using System.Security.Principal;
using System.Web;
using System.Web.Script.Serialization;
using System.Web.Security;

namespace MeetingAssistant.Extension.Common
{
    /// <summary>
    /// 实例化的时候传入票据和自定义数据
    /// </summary>
    /// <typeparam name="TUserData"></typeparam>
    public class MyFormsPrincipal<TUserData> : IPrincipal where TUserData : class, new()
    {
        private IIdentity _identity;
        private TUserData _userData;

        public MyFormsPrincipal(FormsAuthenticationTicket ticket, TUserData userData)
        {
            if (ticket == null)
                throw new ArgumentException("ticket");
            if (userData == null)
                throw new ArgumentException("userData");

            _identity = new FormsIdentity(ticket);
            _userData = userData;
        }
        public TUserData UserData
        {
            get { return _userData; }
        }
        public IIdentity Identity
        {
            get { return _identity; }
        }
        public bool IsInRole(string role)
        {
            //把判断用户组的操作留给UserData去实现
            IPrincipal principal = _userData as IPrincipal;
            if (principal == null)
                throw new NotImplementedException();
            else
                return principal.IsInRole(role);
        }
        /// <summary>
        /// 通过cookie解密，读取用户信息到HttpContext.Current.User
        /// </summary>
        public static void TrySetUserInfo(HttpContext context)
        {
            if (context == null)
                throw new ArgumentNullException("context");
            //读取登录cookie
            HttpCookie cookie = context.Request.Cookies[FormsAuthentication.FormsCookieName];
            if (cookie == null || string.IsNullOrEmpty(cookie.Value)) return;
            try
            {
                TUserData userData = null;
                //解密cookie值 获取FormsAuthenticationTicket对象
                FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(cookie.Value);
                if (ticket != null && string.IsNullOrEmpty(ticket.UserData) == false)
                    //还原用户数据
                    userData = (new JavaScriptSerializer()).Deserialize<TUserData>(ticket.UserData);
                if (ticket != null && userData != null)
                    //构造我们的MyFormsPrincipal实例，重新给context.User赋值
                    context.User = new MyFormsPrincipal<TUserData>(ticket, userData);
            }
            catch {
                //有异常也不要抛出，防止攻击者试探
            }
        }
    }
    
}